11. WateringService
Watering IntentService
In this exercise we will start by creating an IntentService class called PlantWateringService that extends from IntentService.
public class PlantWateringService extends IntentService
To keep things organized, it’s best to define the actions that the IntentService can handle, we will start by defining our first action as ACTION_WATER_PLANTS
public static final String ACTION_WATER_PLANTS =
"com.example.android.mygarden.action.water_plants";
Next we will create a static method called startActionWaterPlants that allows explicitly triggering the Service to perform this action, inside simply create an intent that refers to the same class and set the action to ACTION_WATER_PLANTS and call start service
public static void startActionWaterPlants(Context context) {
Intent intent = new Intent(context, PlantWateringService.class);
intent.setAction(ACTION_WATER_PLANTS);
context.startService(intent);
}
To handle this action we need to override onHandleIntent, where you can extract the action and handle each action type separately
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_WATER_PLANTS.equals(action)) {
handleActionWaterPlants();
}
}
}
Then finally we implement the handleActionWaterPlants method.
To water all plants we just run an update query setting the last watered time to now, but only for those plants that are still alive.
To check if a plant is still alive, you can compare the last watered time with the time now and if the difference is larger than MAX_AGE_WITHOUT_WATER, then the plant is dead!
private void handleActionWaterPlants() {
Uri PLANTS_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH_PLANTS).build();
ContentValues contentValues = new ContentValues();
long timeNow = System.currentTimeMillis();
contentValues.put(PlantContract.PlantEntry.COLUMN_LAST_WATERED_TIME, timeNow);
// Update only plants that are still alive
getContentResolver().update(
PLANTS_URI,
contentValues,
PlantContract.PlantEntry.COLUMN_LAST_WATERED_TIME+">?",
new String[]{String.valueOf(timeNow - PlantUtils.MAX_AGE_WITHOUT_WATER)});
}
Now that we have our IntentService ready, let’s add the water drop image to our widget’s layout
<ImageView
android:id="@+id/widget_water_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/water_drop_blue" />
Just like we did earlier, we need to create a PendingIntent to handle the click event on the water drop image, this time however launching a service instead of an activity
// Add the wateringservice click handler
Intent wateringIntent = new Intent(context, PlantWateringService.class);
wateringIntent.setAction(PlantWateringService.ACTION_WATER_PLANTS);
PendingIntent wateringPendingIntent = PendingIntent.getService(
context,
0,
wateringIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.widget_water_button, wateringPendingIntent);